﻿using System;
using System.Collections.Generic;
using System.Web;
using System.Reflection;

namespace LibraryA.Utils
{
    /// <summary>
    /// creates new object of any type having parameterless constructor
    /// </summary>
    public class FastActivator
    {        
        private static Dictionary<Type, activateDlg> delegateDictionary = new Dictionary<Type, activateDlg>();

        private delegate object activateDlg();
        private static MethodInfo activateMethod = typeof(FastActivator).GetMethod("activate", BindingFlags.Static | BindingFlags.NonPublic);

        private static object activate<T>() where T : new()
        {
            return new T();
        }

        public static object CreateInstance(Type type)
        {
            activateDlg activate = null;
            delegateDictionary.TryGetValue(type, out activate);

            if (activate == null)
            {
                if (type.GetConstructor(System.Type.EmptyTypes) == null) throw new ArgumentException("Instantiated type should have instance public parameterless constructor");

                activate = (activateDlg)Delegate.CreateDelegate(typeof(activateDlg), activateMethod.MakeGenericMethod(type));
                delegateDictionary[type] = activate;
            }

            return activate();
       }        
    }
}
